package com.yyge.controller.front.sms;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yyge.common.constans.RedisConstans;
import com.yyge.common.enums.AckCode;
import com.yyge.common.vo.resp.R;
import com.yyge.controller.front.sms.req.CodeReq;
import com.yyge.entity.Merchandiser;
import com.yyge.service.MerchandiserService;
import com.yyge.util.sms.SMSLogin;
import com.yyge.util.sms.SmsTemplate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Api(tags = "前端-短信API")
@RestController
@RequestMapping(value = "/api/front")
public class FrontSmsContrller {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MerchandiserService merchandiserService;

    /**
     * 给 element-ui中的 表单认证用的,必须要返回 ok(大家要注意注意注意)
     * @param loginName
     * @return
     */
    @ApiOperation(value = "手机是否被占用")
    @GetMapping(value = "/loginName/{loginName}/exists")
    public R loginNameExists(@PathVariable(value = "loginName") String loginName){

        LambdaQueryWrapper<Merchandiser> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Merchandiser::getLoginName, loginName);
        // select count(*) from merchandiser where login_name=?
        long count=this.merchandiserService.count(queryWrapper);

        R<Object> ok = R.ok();
        if(count>0){
            ok.setData(AckCode.EXISTS_VALUE.getMsg());
        }
        return ok;
    }

    @ApiOperation(value = "注册发送短信")
    @GetMapping(value = "/sms/register/{phone}")
    public R regisgerSendSms( @PathVariable(value = "phone") String loginName) throws ExecutionException, InterruptedException {
        if(StrUtil.isBlank(loginName)){
            return R.build(AckCode.SYSTEM_PARAM_FAIL);
        }

        //检查格式对不对
        final String  regex="^0?(13|15|17|18|14|19)[0-9]{9}$";
        //创建表达式
        Pattern pattern = Pattern.compile(regex);
        //创建匹配模型
        Matcher matcher = pattern.matcher(loginName);
        if(!matcher.matches()){
            return R.build(AckCode.ENTERPRISE_PHONE_ERROR);
        }

        //3、调用阿里云发短信(空着不写)
        //验证码4位数 1000-9999


        SMSLogin sms=new SMSLogin(loginName,4);
        SmsTemplate smsTemplate=new SmsTemplate();
        smsTemplate.sendSms(sms);
        String code=sms.getCode();
        System.out.println("您的验证码为:");
        System.out.println(code);

        //4、存放到redis中
        String rediskey= RedisConstans.getRedisKey(RedisConstans.SMS_KEY,loginName);
        this.redisTemplate.opsForValue().set(rediskey,code,RedisConstans.SMS_EXPIRED_MINUTES, TimeUnit.MINUTES);

        //5、结果给前端
        Map<String,Object> dataMap=new HashMap<>();
        dataMap.put("expired",RedisConstans.SMS_EXPIRED_MINUTES *60);

        return R.okHasData(dataMap);
    }

    @ApiOperation(value = "验证码验证")
    @PostMapping(value = "/sms/register/validate")
    public R validataRegister(@RequestBody @Valid CodeReq req){
        //1、验证码判断
        String rediskey=RedisConstans.getRedisKey(RedisConstans.SMS_KEY,req.getPhone());
        Object redisValue=this.redisTemplate.opsForValue().get(rediskey);
        if(Objects.isNull(redisValue)){
            return  R.build(AckCode.SMS_CODE_OVERTIME);
        }
        if(!redisValue.toString().equalsIgnoreCase(req.getCode())){
            return R.build(AckCode.SMS_CODE_WRONG);
        }

        //删除验证码
        this.redisTemplate.delete(rediskey);

         //2、验证手机号是存在，如果存在，不允许再操作
        LambdaQueryWrapper<Merchandiser> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Merchandiser::getLoginName,req.getPhone());

        long count=this.merchandiserService.count(lambdaQueryWrapper);
        if(count>0){
            return R.build(AckCode.EXISTS_VALUE);
        }else{
            return R.ok();
        }
    }
}
